import json
import pickle
import tarfile

from flask import Flask
from flask import request
import random
import requests
import Treenode
from pypbc import *

nodedatas = {
    'node1': {'t': None, 'qx': None, 'userpk': None},
    'node2': {'t': None, 'qx': None, 'userpk': None},
    'node3': {'t': None, 'qx': None, 'userpk': None},
    'node4': {'t': None, 'qx': None, 'userpk': None},
    'node5': {'t': None, 'qx': None, 'userpk': None},
}

ppfile = open('./sys/pairingparams.txt', 'r')
params = Parameters(ppfile.read())
pairing = Pairing(params)


def randomP(d, s, pairing):
    coef = []
    coef.append(s)
    for i in range(0, d):
        coef.append(Element.random(pairing, Zr))
    return coef

def getY(index,coef,pairing):
    print('gety')
    res = coef[0]
    index = Element(pairing,Zr,value=index)
    print('index',index)
    for i in range(len(coef)):
        exp = Element(pairing,Zr,value=i)
        res = res.__add__(coef[i].__mul__(index.__pow__(exp)))
    return res

app = Flask(__name__)


#
#
# sys
@app.route("/applykey", methods=['POST'])
def KEYGEN():
    Nodelist = ['localhost:5000', 'localhost:5000', 'localhost:5000', 'localhost:5000', 'localhost:5000',
                'localhost:5000', 'localhost:5000', 'localhost:5000', 'localhost:5000', 'localhost:5000']

    mkfile = open('./sys/MK.txt')
    MK = eval(mkfile.read())
    mkfile.close()

    # 直接获取文件内容
    # file_context = request.files['files'].stream.read()

    # 此处最好再把文件另存一下
    # ACT = pickle.loads(file_context)
    u = json.loads(request.form.get('ACTu'))
    userpk = request.form.get('pk')
    selectnodes = random.sample(Nodelist, len(u) + 1)
    for index in range(0, len(u)):
        t = u[index]
        print('send t' + str(t) + ' to node' + str(t))
        requests.post('http://' + selectnodes[index + 1] + '/node/gett/' + str(t),
                      data={'t': MK['t' + str(t)], 'userpk': userpk})

    print('start conn ma')
    # print(ACT)
    files = {'files': open('./user/ACT.pkl', 'rb')}
    response = requests.post('http://localhost:5000/keygen/ma',
                             data={'y': MK['y'], 'selectnodes': json.dumps(selectnodes[1:])},
                             files=files)
    D = response.json()
    print('sys get origin D:', D)

    # 对D签名

    return json.dumps(D)


#
#
# MA
@app.route("/keygen/ma", methods=['POST'])
def MAGenKey():
    print('ma start')
    file_context = request.files['files'].stream.read()
    ACT = pickle.loads(file_context)
    y = request.form.get('y')
    y = Element(pairing, Zr, value=int(y,16))
    selectnodes = json.loads(request.form.get('selectnodes'))
    print('ma', selectnodes)
    D = []

    def KeyGen(ACT, y):
        d = ACT.value - 1
        # ACT.poly.append(y)
        # for i in range(0, d):
        #     ACT.poly.append(random.randint(1, 10))
        ACT.poly = randomP(d, y, pairing)
        #ACT.poly.reverse()

        for i in range(len(ACT.child)):
            print('index',ACT.child[i].index)
            b = getY(ACT.child[i].index,ACT.poly,pairing)
            print('b',b)
            GenPoly(ACT.child[i], b)
        return

    def GenPoly(child, b):
        d = child.value - 1
        # child.poly.append(b)
        # for i in range(0, d):
        #     child.poly.append(random.randint(1, 10))
        child.poly = randomP(d, b, pairing)
        #child.poly.reverse()

        if (child.type == 'attr'):
            qx = child.poly[0]
            Di = requests.post('http://' + 'localhost:5000' + '/node/getqx/' + str(child.value),
                               data={'qx': qx.__str__()}).text
            D.append([Di, child.value])
            return
        lens = len(child.child)
        if lens != 0:
            for i in range(len(child.child)):
                b = getY(child.child[i].index,child.poly,pairing)
                GenPoly(child.child[i], b)

    # context = type(ACT)
    # D=KeyGen(ACT,MK)#猜测问题是经过传递后act不再是一个对象造成函数执行错误
    KeyGen(ACT, y)
    # print('ma recv D', D)
    return json.dumps(D)


#
#
# node
@app.route("/node/gett/<string:id>", methods=['POST'])
def getT(id):
    node = 'node' + id
    nodedatas[node]['t'] = request.form.get('t')
    nodedatas[node]['userpk'] = request.form.get('userpk')
    print(node + ' get t:' + nodedatas[node]['t'])
    return 'node getT'


@app.route('/node/getqx/<string:id>', methods=['POST'])
def getQx(id):
    node = 'node' + id
    nodedatas[node]['qx'] = request.form.get('qx')
    print(node + ' get qx:' + str(nodedatas[node]['qx']))

    response = requests.get('http://localhost:5000/node/genkey/' + id)
    Di = response.text
    return Di


@app.route('/node/genkey/<string:id>', methods=['GET'])
def nodeGenKey(id):
    node = 'node' + id
    t = nodedatas[node]['t']
    qx = nodedatas[node]['qx']

    pkfile = open('./sys/PK.txt', 'r')
    PK = eval(pkfile.read())
    g = PK['g']
    #print(g)
    g = Element(pairing, G1, value=g)
    #print('g',g)
    #print(t)
    t = Element(pairing, Zr, value=int(t,16))
    #print('t',t)
    #print(qx)
    qx = Element(pairing, Zr, value=int(qx,16))
    #print('qx',qx)

    # Di = int(g,16)** (int(qx[0]) / int(t))
    Di = g.__pow__(qx.__mul__(t.__pow__(-1)))

    # print(Di)
    # 将di用用户公钥加密一下，正常应该是传入用户ip，node自己去查，此处为了方便测试通过sys传过来
    # userpk = nodedatas[node]['userpk']
    # Di = Di*int(userpk)
    #print(Di)

    nodedatas[node]['t'] = None
    nodedatas[node]['qx'] = None
    nodedatas[node]['userpk'] = None
    print(node+'return DI\n')
    # return json.dumps(Di)
    return Di.__str__()
